package com.wallace.downloadserver.netty.handler.inbound

import com.wallace.downloadserver.netty.NettyManager
import com.wallace.downloadserver.netty.NettyMsg
import com.wallace.downloadserver.util.myEncrypt.AESCryptUtil
import com.wallace.downloadserver.util.myEncrypt.AESKey
import com.wallace.downloadserver.util.myJson.JsonUtil
import io.netty.buffer.ByteBuf
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.SimpleChannelInboundHandler
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.net.InetSocketAddress

/**
 * @Description:
 * Netty消息解密处理
 * @author Wallace
 * @Date 2022/2/14 9:34
 */
@Component
class NettyMsgDecryptHandler(private var nettyManager: NettyManager) : SimpleChannelInboundHandler<ByteArray>() {

    private val log: Logger = LoggerFactory.getLogger(NettyMsgDecryptHandler::class.java)

    private var aesKey: AESKey? = null

    override fun channelRegistered(ctx: ChannelHandlerContext?) {
        val ip = (ctx?.channel()?.remoteAddress() as? InetSocketAddress)?.address?.hostAddress
        if (ip != null) {
            aesKey = nettyManager.initAesKey(ip)
            if (aesKey != null) {
                log.info("client[${ip}]:success to register")
            }
        }
        ctx?.fireChannelRegistered()
    }

    override fun channelRead(ctx: ChannelHandlerContext?, msg: Any?) {
        val s = (msg as? ByteBuf)?.toString(Charsets.UTF_8)
        log.debug("channelRead = $s")
        super.channelRead(ctx, msg)
    }

    override fun channelRead0(ctx: ChannelHandlerContext?, msg: ByteArray?) {
        log.debug("channelRead0")
        val plainByteArray = msg?.let { AESCryptUtil.decryptAfterDecode(it, aesKey!!.getSecretKeySpec(), aesKey!!.iv) }
        if (plainByteArray?.isNotEmpty() == true) {
            val jsonString = plainByteArray.toString(Charsets.UTF_8)
            val nettyMsg = JsonUtil.toAny(jsonString, NettyMsg::class.java)
            nettyMsg?.let {
                log.info("receive message from client[${ctx?.channel()?.remoteAddress()}] : $it")
                // 消息传递给下一个handler
                ctx?.fireChannelRead(it)
            }
        }
    }
}